﻿using System;
using System.Diagnostics;
using System.Media;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using Rabbit.BusinessLogicLayer;
using Rabbit.Controls;
using Rabbit.Model;
using Rabbit.Utils;
using MicroBlogClient.Pages;
using System.Collections.Generic;
using System.Windows.Interop;
namespace MicroBlogClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// to be refined
    /// </summary>
    public partial class MainWindow : BaseWindow
    {
        #region Private Fields
        Properties.Settings AppSettings = new Properties.Settings();
        public Status CurrentOperatingStatus;
        public Comment CurrentOperatingComment;
        public bool IsOperatingOrignalStatus = false;
        public SoundPlayer Player = new SoundPlayer(Application.GetResourceStream(new Uri("Resources/Sound/Drip.wav", UriKind.RelativeOrAbsolute)).Stream);
        private Action RefreshUserInformation;
        private int FollowersCount = 0;
        private DispatcherTimer timerRefreshUserInformation;
        #endregion

        #region Constructure
        public MainWindow() 
        {
            InitializeComponent();
            Win32.MinWidth = MinWidth;
            Win32.MinHeight = MinHeight;

            this.Deactivated += new EventHandler(MainWindow_Deactivated);
        }

        void MainWindow_Deactivated(object sender, EventArgs e)
        {
            ReleaseMemory();
        }
        private void ReleaseMemory()
        {
#if DEBUG
            Win32.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
#endif
            GC.Collect(2);
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
             base.OnSourceInitialized(e); 
        }
 
         
        private bool RegisterHotKey(UserSettings setting)
        {
            HotKeyGenerateTextBox tb = new HotKeyGenerateTextBox();
            string registerFailedMessage = "";
            try
            {
                tb.Text = setting.CaptureScreenHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper hk = new HotKeyHelper(this, tb.ModifierKey, tb.KeyCode);
                    hk.OnHotKeyClicked = () => { ucPublisStatus.ShowCaptureScreen(); };
                }
            }
            catch
            {
                registerFailedMessage = Environment.NewLine + "截屏:" + setting.CaptureScreenHotKey;
            }

            try
            {
                tb.Text = setting.GetLetterHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper hk = new HotKeyHelper(this, tb.ModifierKey, tb.KeyCode);
                    hk.OnHotKeyClicked = () => { FlushMyLetterPool(null, null); };
                }
            }
            catch
            {
                //setting.GetLetterHotKey = "无";
                registerFailedMessage += Environment.NewLine +"获取私信:" + setting.GetLetterHotKey;
            }

            try
            {
                tb.Text = setting.GetStatusHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper hk = new HotKeyHelper(this, tb.ModifierKey, tb.KeyCode);
                    hk.OnHotKeyClicked = () => { FlushFriendsStatusPool(null, null); };
                }
            }
            catch 
            {
                //setting.GetStatusHotKey = "无";
                registerFailedMessage += Environment.NewLine + "获取微博:" + setting.GetStatusHotKey;
            }

            try
            {
                tb.Text = setting.GetCommentHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper hk = new HotKeyHelper(this, tb.ModifierKey, tb.KeyCode);
                    hk.OnHotKeyClicked = () => { FlushMyCommentStatusPool(null, null); };
                }
            }
            catch 
            {
                //setting.GetCommentHotKey = "无";
                registerFailedMessage += Environment.NewLine + "获取评论:" + setting.GetCommentHotKey;
            }

            try
            {
                tb.Text = setting.GetMetionedMeHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper hk = new HotKeyHelper(this, tb.ModifierKey, tb.KeyCode);
                    hk.OnHotKeyClicked = () => { FlushMetionedMeStatusPool(null, null); };
                }
            }
            catch
            {
                //setting.GetMetionedMeHotKey = "无";
                registerFailedMessage += Environment.NewLine + "提到我:" + setting.GetMetionedMeHotKey;
            }

            if (!string.IsNullOrEmpty(registerFailedMessage))
            {
                MessageBox.Show("注册热键失败，这些热键已经被其他程序占用,请重新设置：" + registerFailedMessage);
                return false;
            }

            Me.UserSettings = setting;
            return true;
        }

        private void SaveSettings()
        {
            int userLocation = AppSettings.UserList.FindIndex(u => u.UserID == Me.Id);
            if (userLocation == -1)
            {
                AppSettings.UserList.Add(Me.UserSettings);
            }
            else
            {
                AppSettings.UserList[userLocation] = Me.UserSettings;
            }

            UserBL.CurrentUser.UserSettings = Me.UserSettings;

            AppSettings.Save();
            AppSettings.Reload();
        }
        private void UnRegisterHotKey(UserSettings settings)
        {
            HotKeyGenerateTextBox tb = new HotKeyGenerateTextBox();
            string registerFailedMessage = "";
            try
            {
                tb.Text = settings.CaptureScreenHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper.Unregister(tb.ModifierKey, tb.KeyCode);
                }
            }
            catch
            {
            }

            try
            {
                tb.Text = settings.GetLetterHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper.Unregister(tb.ModifierKey, tb.KeyCode);
                }
            }
            catch
            {
            }

            try
            {
                tb.Text = settings.GetStatusHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper.Unregister(tb.ModifierKey, tb.KeyCode);
                }
            }
            catch
            {
            }

            try
            {
                tb.Text = settings.GetCommentHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper.Unregister(tb.ModifierKey, tb.KeyCode);
                }
            }
            catch
            {
                registerFailedMessage += "获取评论、";
            }

            try
            {
                tb.Text = settings.GetMetionedMeHotKey;
                if (tb.IsValidHotKey)
                {
                    HotKeyHelper.Unregister(tb.ModifierKey, tb.KeyCode);
                }
            }
            catch
            {
            } 
        }
        #endregion

        #region Sync UserInformation
        private void StartSyncUserInformation()
        {
            timerRefreshUserInformation = new DispatcherTimer();
            timerRefreshUserInformation.Interval = TimeSpan.FromSeconds(Me.UserSettings.UpdateInterval.Value);
            timerRefreshUserInformation.Tick += new EventHandler(timerRefreshUserInformation_Tick);
            timerRefreshUserInformation.Start();
        }

        void timerRefreshUserInformation_Tick(object sender, EventArgs e)
        {
            if (RefreshUserInformation == null)
            {
                RefreshUserInformation = () =>
                {
                    try
                    {
                        User tempUser = UserBL.GetCurrentUserInformation();
                        if (FollowersCount == 0)
                        {
                            FollowersCount=Me.FollowersCount;
                        }
                        this.Dispatcher.BeginInvoke((Action)delegate()
                        {
                            Me = tempUser;

                            int increasedFollowersCount = tempUser.FollowersCount - FollowersCount;
                            if (increasedFollowersCount > 0)
                            {
                                NewFollowersCount = increasedFollowersCount;
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                        LogHelper.LogError(ex);
                    }
                };
            }

            RefreshUserInformation.Invoke();
        }

        #endregion

        #region Dependency Property
        public User Me
        {
            get { return (User)GetValue(MeProperty); }
            set { SetValue(MeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Me.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MeProperty =
            DependencyProperty.Register("Me", typeof(User), typeof(MainWindow), new UIPropertyMetadata(UserBL.CurrentUser));

        public User CurrentUser
        {
            get { return (User)GetValue(CurrentUserProperty); }
            set { SetValue(CurrentUserProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentUser.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentUserProperty =
            DependencyProperty.Register("CurrentUser", typeof(User), typeof(MainWindow), new UIPropertyMetadata(new User()));

        public bool IsReplyToStatus = false;
        public bool IsReplyToComment = false;

        public int NewFollowersCount
        {
            get { return (int)GetValue(NewFollowersCountProperty); }
            set { SetValue(NewFollowersCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewFollowersCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewFollowersCountProperty =
            DependencyProperty.Register("NewFollowersCount", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));


        public int NewLetterCount
        {
            get { return (int)GetValue(NewLetterCountProperty); }
            set { SetValue(NewLetterCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewLetterCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewLetterCountProperty =
            DependencyProperty.Register("NewLetterCount", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));

        public int NewCommentsCount
        {
            get { return (int)GetValue(NewCommentsCountProperty); }
            set { SetValue(NewCommentsCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewCommentsCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewCommentsCountProperty =
            DependencyProperty.Register("NewCommentsCount", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));

        public int NewMetionedMeCount
        {
            get { return (int)GetValue(NewMetionedMeCountProperty); }
            set { SetValue(NewMetionedMeCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewMetionedMeCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewMetionedMeCountProperty =
            DependencyProperty.Register("NewMetionedMeCount", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));

        public int NewFriendsStatusCount
        {
            get { return (int)GetValue(NewFriendsStatusCountProperty); }
            set { SetValue(NewFriendsStatusCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewFriendsStatusCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewFriendsStatusCountProperty =
            DependencyProperty.Register("NewFriendsStatusCount", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));
        #endregion

        #region TitleBarButton Click Event
        private void btnTitleBarMin_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
        }

        private void btnTitleBarClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source is Canvas || e.Source is TextBlock)
            {
                base.DragMove();
            }
        }

        private void btnTitleBarMaximze_Click(object sender, RoutedEventArgs e)
        {
            if (WindowState != System.Windows.WindowState.Maximized)
            {
                WindowState = System.Windows.WindowState.Maximized;
            }
            else
            {
                WindowState = System.Windows.WindowState.Normal;
            }
        }

        private void ContentControl_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (WindowState == System.Windows.WindowState.Maximized)
            {
                WindowState = System.Windows.WindowState.Normal;
            }
            else
            {
                WindowState = System.Windows.WindowState.Maximized;
            }
        }
        #endregion

        #region Message Helper
        public void showProcessingMessage(string message)
        {
            popupTextBlockText.Text = message;
            popupImageIcon.Content = this.FindResource("ProcessingMessageIcon");

            (this.FindResource("StoryBoardPopupAnimation") as Storyboard).Stop();
            popupMessageContainer.Visibility = System.Windows.Visibility.Visible;
            popupMessageContainer.Opacity = 1;
        }

        public void showSuccessfulMessage(string message)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                popupMessageContainer.SetCurrentValue(Border.VisibilityProperty, Visibility.Visible);
                popupTextBlockText.Text = message;
                popupImageIcon.Content = this.FindResource("OKMessageIcon");
                (this.FindResource("StoryBoardPopupAnimation") as Storyboard).Begin();
            }));
        }

        public void hideMessage()
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                popupMessageContainer.SetCurrentValue(Border.VisibilityProperty, Visibility.Collapsed);
            }));
        }
        public void showFailedMessage(string message)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                popupMessageContainer.SetCurrentValue(Border.VisibilityProperty, Visibility.Visible);
                popupTextBlockText.Text = message; 

                popupImageIcon.Content = this.FindResource("FailMessageIcon");
                (this.FindResource("StoryBoardPopupAnimation") as Storyboard).Begin();
            }));
        }

        public void showFailedMessage(MaxRatesExceededException ex)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                popupMessageContainer.SetCurrentValue(Border.VisibilityProperty, Visibility.Visible);
                popupTextBlockText.Text = "超过最大次数访问上限，该限制将在" + ex.RatesInformation.ResetTime + "后自动解除";

                popupImageIcon.Content = this.FindResource("FailMessageIcon");
                (this.FindResource("StoryBoardPopupAnimation") as Storyboard).Begin();
            }));
        }
        #endregion
         
        private void statusImage_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ImageEx img = sender as ImageEx;
            if (img != null)
            {
                PictureViewer pv = new PictureViewer();
                pv.PictureSource = img.LargerPictureSource;
                pv.ShowActivated = true;
                pv.Show();
            }
            e.Handled = true;
        }

        public void FlushFriendsStatusPool(object sender, MouseButtonEventArgs e)
        {
            ShowAndActivate();
            tabMainControl.SelectedItem = tabItemStatus;
            (frmFriendsStatus.Content as PageBase).DoWork();
        }

        public void FlushMyCommentStatusPool(object sender, MouseButtonEventArgs e)
        {
            ShowAndActivate();
            tabMainControl.SelectedItem = tabItemMyComments;
            (frmComments.Content as PageBase).DoWork();
        }

        public void FlushMetionedMeStatusPool(object sender, MouseButtonEventArgs e)
        {
            ShowAndActivate();
            tabMainControl.SelectedItem = tabItemMetionedMe;
            (frmMetionedMe.Content as PageBase).DoWork();
        }

        public void FlushMyLetterPool(object sender, MouseButtonEventArgs e)
        {
            ShowAndActivate();
            tabMainControl.SelectedItem = tabItemMyLetters;
            (frmLetter.Content as PageBase).DoWork();
        }

        private void menuCopyStatus_Click(object sender, RoutedEventArgs e)
        {
            string text = (sender as MenuItem).CommandParameter.ToString();
            Clipboard.SetText(text);
        }
        bool IsLogOn = false;
        public void btnTitleBarSettings_Click(object sender, RoutedEventArgs e)
        {
            ShowAndActivate();
            if (IsLogOn)
            {
                ucSettings.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                MessageBox.Show("请先登录","未登录", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// this method is called from the pages to show and activate main window
        /// </summary>
        public void ShowAndActivate()
        {
            if (!this.IsActive)
            {
                this.Show();
                this.Activate();
            }
        }

        private void ucSettings_OnSettingsCancel(object sender, RoutedEventArgs e)
        {
            this.Opacity = Me.UserSettings.MainWindowOpacity.Value;
        }

        private void ucSettings_OnSettingsSaved(object sender, OneValueEventArgs<UserSettings> e)
        {
            //unregister old hot keys
            UnRegisterHotKey(Me.UserSettings);

            //try register new hot keys
            bool isNewKeysRegistered = RegisterHotKey(e.Value);

            //if register new hotkeys failed, unregister the registered hot keys
            //and re-register the old hot keys
            if (!isNewKeysRegistered)
            {
                UnRegisterHotKey(e.Value);
                RegisterHotKey(Me.UserSettings);
            }
            else
            {
                ucSettings.Visibility = System.Windows.Visibility.Collapsed;

                PageBase.MySettings = e.Value;
                UserBL.CurrentUser.UserSettings = e.Value;
                Me.UserSettings = e.Value;
                SaveSettings();

                showSuccessfulMessage("设置成功，已生效");
            }
        }
        private void ucSettings_OnMainWindowOpacityChanged(object sender, OneValueEventArgs<double> e)
        {
            this.Opacity = e.Value;
        }

        private void mainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.Hide();
            e.Cancel = true;
        }

        
        private void UserHeadPicture_MouseEnter(object sender, MouseEventArgs e)
        {
            popupUserInformation.PlacementTarget = sender as UIElement;
            if (popupUserInformation.IsOpen)
            {
                popupUserInformation.IsOpen = false;
            }

            ListBoxItem item = Rabbit.Utils.Common.GetListBoxItemFromChild(sender as DependencyObject);

            if (item.Content.GetType() == typeof(Status))
            {
                CurrentUser = (item.Content as Status).User;
            }
            else if (item.Content.GetType() == typeof(Comment))
            {
                CurrentUser = (item.Content as Comment).User;
            }

            popupUserInformation.IsOpen = true;
        }

        private void UserHeadPicture_MouseLeave(object sender, MouseEventArgs e)
        {
            if (!popupUserInformation.IsMouseOver)
            {
                popupUserInformation.IsOpen = false;
            }
        }
         
        private void linkSendLetterToCurrentUser_Click(object sender, RoutedEventArgs e)
        {
            long userID = CurrentUser.Id;
            string userName = CurrentUser.ScreenName;
            showProcessingMessage("正在验证是否可以发私信");
            if (CurrentUser.Id == Me.Id)
            {
                showFailedMessage("不能给自己发私信");
            }
            else
            {
                Action checkingAction = () =>
                {
                    if (UserBL.CheckIsFollowingMe(userID))
                    {
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            popupMessageContainer.Visibility = System.Windows.Visibility.Collapsed;

                            popupUserInformation.IsOpen = false;
                            tabMainControl.SelectedItem = tabItemMyLetters;
                            (frmLetter.Content as PageBase).DoWork(CurrentUser);
                        }));
                    }
                    else
                    {
                        showFailedMessage(userName + "没有关注你，不能给他发私信");
                    }
                };
                checkingAction.BeginInvoke(null, null);
            }
        }

        private void InvokeStartingEvent(object sender, OneValueEventArgs<string> e)
        {
            showProcessingMessage(e.Value);
        }

        private void InvokeFailedEvent(object sender, OneValueEventArgs<string> e)
        {
            showFailedMessage(e.Value);
        }

        private void InvokeFinishedEvent(object sender, OneValueEventArgs<string> e)
        {
            showSuccessfulMessage(e.Value);
        }

        private void linkAskForFollowedCurrentUser_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentUser.Id == Me.Id)
            {
                showFailedMessage("自己无法关注自己");
            }
            else
            {
                string message = "@" + CurrentUser.ScreenName + "  " + "互粉啦[微笑]";
                showProcessingMessage("正在发送求关注请求");
                Action publishDelegate = () =>
                {
                    try
                    {
                        Status status = StatusesBL.UpdateMyStatus(message);
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            (frmFriendsStatus.Content as PageBase).DoWork(status);
                        }));
                        showSuccessfulMessage("求关注成功,对方将收到你的请求");
                    }
                    catch
                    {
                        showFailedMessage("求关注失败,请重试");
                    }
                };
                publishDelegate.BeginInvoke(null, null);
            }
        }

        private void linkRemoveFriendCurrentUser_Click(object sender, RoutedEventArgs e)
        {
            long userID = CurrentUser.Id;
            if (userID == Me.Id)
            {
                showFailedMessage("你无法取消关注你自己");
            }
            else
            {
                Action removeFriendshipAction = () =>
                {
                    try
                    {
                        if (UserBL.RemoveFriendship(userID) != null)
                        {
                            showSuccessfulMessage("取消关注成功");
                            this.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                CurrentUser.Following = false;
                            }));
                        }
                    }
                    catch
                    {
                        showFailedMessage("取消关注失败,有可能是因为您尚未关注他");
                    }
                };
                removeFriendshipAction.BeginInvoke(null, null);
            }
        }

        private void linkCreateFriendshipWithCurrentUser_Click(object sender, RoutedEventArgs e)
        {
            showProcessingMessage("正在添加关注");
            long userID = CurrentUser.Id;
            Action makeFriends = () =>
            {
                try
                {
                    User result = UserBL.CreateFriendship(userID);
                    this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            CurrentUser.Following = true;
                        }));
                    showSuccessfulMessage("关注成功");
                }
                catch (MaxRatesExceededException ex)
                {
                    showFailedMessage("操作超过最大次数限制，将在" + ex.RatesInformation.ResetTime + "后解除");
                }
                catch (Exception)
                {
                    showFailedMessage("添加关注失败，您已经关注过此人");
                }
            };
            makeFriends.BeginInvoke(null, null);
        }
 
        private void popupUserInformation_MouseLeave(object sender, MouseEventArgs e)
        {
            popupUserInformation.IsOpen = false;
        }
         
        private void ucPublisStatus_OnPublishFinished(object sender, OneValueEventArgs<Status> e)
        {
            (frmFriendsStatus.Content as PageBase).DoWork(e.Value);
            showSuccessfulMessage("发表成功");
        }

        private void linkOpenUserBlog_Click(object sender, RoutedEventArgs e)
        {
            OpenUserPageOnWebPage_Click(null, null);
        }

        private void linkOpenUserInBrowser(object sender, RoutedEventArgs e)
        {
            Rabbit.Utils.Common.OpenUserPage(CurrentUser.Id);
        }

        private void OpenUserPageOnWebPage_Click(object sender, MouseButtonEventArgs e)
        { 
            (frmUser.Content as UserPage).SetCurrentValue(UserPage.CurrentUserProperty, CurrentUser);
            (frmUser.Content as UserPage).Operation = OperationType.Status;
            (frmUser.Content as UserPage).IsLoadingByNickName = false;
            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }

            if (e!=null)
            {
                e.Handled = true;
            }
        }

        public void OpenUserStatusByName(string userName)
        {
            (frmUser.Content as UserPage).Operation = OperationType.Status;
            (frmUser.Content as UserPage).IsLoadingByNickName =true;
            (frmUser.Content as UserPage).UserName = userName;
            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }
        }

        private void OpenMyFollowingOnWebPage_Click(object sender, MouseButtonEventArgs e)
        {
            (frmUser.Content as UserPage).CurrentUser = Me;
            (frmUser.Content as UserPage).Operation = OperationType.Following;
            if (tabMainControl.SelectedItem !=tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }

            e.Handled = true;
        }
        private void OpenMyFollowersOnWebPage_Click(object sender, MouseButtonEventArgs e)
        {
            //set new followers count to 0 so that the new follower tip won't show on UI
            NewFollowersCount = 0;

            // set FollowersCount to current followers count to prepare for next update
            FollowersCount = Me.FollowersCount;

            (frmUser.Content as UserPage).CurrentUser = Me;
            (frmUser.Content as UserPage).Operation = OperationType.Follower;
            (frmUser.Content as UserPage).IsLoadingByNickName = false;
            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }
            e.Handled = true;
        }

        private void OpenMyStatusOnWebPage_Click(object sender, MouseButtonEventArgs e)
        {
            //Rabbit.Utils.Common.OpenWebPage(App.Current.Resources["ProfileUrlPrefix"].ToString());
            (frmUser.Content as UserPage).Operation = OperationType.Status;
            (frmUser.Content as UserPage).CurrentUser = Me;

            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }
            e.Handled = true;
        }

        private void OpenUserFollowingOnWebPage_Click(object sender, MouseButtonEventArgs e)
        {
            //Rabbit.Utils.Common.OpenWebPage(App.Current.Resources["FollowingUrlPrefix"].ToString() + CurrentUser.Id);
            (frmUser.Content as UserPage).Operation = OperationType.Following;
            (frmUser.Content as UserPage).CurrentUser = CurrentUser;
            (frmUser.Content as UserPage).IsLoadingByNickName = false;
            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }
            e.Handled = true;
        }

        private void OpenUserFollowersOnWebPage_Click(object sender, MouseButtonEventArgs e)
        { 
            //Rabbit.Utils.Common.OpenWebPage(App.Current.Resources["FollowersUrlPrefix"].ToString() + CurrentUser.Id);
            (frmUser.Content as UserPage).Operation = OperationType.Follower;
            (frmUser.Content as UserPage).CurrentUser = CurrentUser;
            (frmUser.Content as UserPage).IsLoadingByNickName = false;
            if (tabMainControl.SelectedItem != tabItemUserPage)
            {
                tabMainControl.SelectedItem = tabItemUserPage;
            }
            else
            {
                (frmUser.Content as UserPage).DoWork();
            }
            e.Handled = true;
        }
         
        private void linkSpeakToSomebody_Click(object sender, RoutedEventArgs e)
        {
            ucPublisStatus.rtbStatus.InsertText("@" + CurrentUser.ScreenName + " ");
        }

        private void ucLogin_OnLoginFinished(object sender, OneValueEventArgs<bool> e)
        {
            Me = UserBL.CurrentUser;
            DataContext = this;

            //start sync user information first
            StartSyncUserInformation();

            //set some
            this.Opacity = Me.UserSettings.MainWindowOpacity.Value;
            ucSettings.SetCurrentValue(UCSettings.VisibilityProperty, Visibility.Hidden);
            if (!RegisterHotKey(Me.UserSettings))
            {
                SaveSettings();
            }
            ucLogin.Visibility = System.Windows.Visibility.Collapsed;
            ucPublisStatus.StartLoading();

            //start loading content
            (frmComments.Content as PageBase).StartLoading();
            (frmFriendsStatus.Content as PageBase).StartLoading();
            (frmLetter.Content as PageBase).StartLoading();
            (frmMetionedMe.Content as PageBase).StartLoading();
            (frmUser.Content as PageBase).StartLoading();

            ucSettings.StartLoadSetting();
            IsLogOn = true;
        }

        //this method will be called in App.cs
        public void Logout()
        {
            //stop fetching new message
            (frmComments.Content as PageBase).StopFetchingMessage();
            (frmFriendsStatus.Content as PageBase).StopFetchingMessage();
            (frmLetter.Content as PageBase).StopFetchingMessage();
            (frmMetionedMe.Content as PageBase).StopFetchingMessage();
            (frmUser.Content as PageBase).StopFetchingMessage();

            //unregister hotkey
            if (Me != null && Me.UserSettings != null)
            {
                UnRegisterHotKey(Me.UserSettings);
            }

            Me = null;
            CurrentUser = null;

            if (timerRefreshUserInformation != null)
            {
                //stop sync user information
                timerRefreshUserInformation.Stop();
                timerRefreshUserInformation = null;
            }

            //set login control to be visible
            ucLogin.Visibility = System.Windows.Visibility.Visible;
            IsLogOn = false;
        }

        List<ChatWindow> ChatWindows = new List<ChatWindow>();

        public void OpenChatWindow(User user,bool checkIsFollowingMe=true)
        {
            int location = ChatWindows.FindIndex(c => c.CurrentUser.Id == user.Id);
            Letters.letterBL.ResetAutoUpadteMessageInterval(20);
            if (location != -1)
            {
                ChatWindows[location].Show();
                ChatWindows[location].Activate();
                ChatWindows[location].WindowState = System.Windows.WindowState.Normal;
            }
            else
            {
                if (checkIsFollowingMe)
                {
                    if (!UserBL.CheckIsFollowingMe(CurrentUser.Id))
                    {
                        showFailedMessage("TA没有关注你，无法发起聊天请求");
                    }
                }

                ChatWindow cw = new ChatWindow();
                if (ChatWindow.Me == null)
                {
                    ChatWindow.Me = Me;
                }

                cw.CurrentUser = user;
                cw.OnWindowClosing = RemoveChatWindow;
                cw.OnSendNewLetter = SendLetter;
                cw.ShowActivated = true;
                cw.Show();

                ChatWindows.Add(cw);
            }
        }

        private void linkChatWithCurrentUser_Click(object sender, RoutedEventArgs e)
        {
            OpenChatWindow(CurrentUser);
        }
        private void RemoveChatWindow(ChatWindow window)
        {
            ChatWindows.Remove(window);
            if (ChatWindows.Count == 0)
            {
                Letters.letterBL.ResetAutoUpadteMessageInterval(AppSettings.UpdateInterval);
            }
        }
        public void NewLetterReceived(List<Letter> letters,out List<Letter> removedLetters)
        {
            removedLetters = new List<Letter>();

            foreach (var letter in letters)
            {
                int location = ChatWindows.FindIndex(c => c.CurrentUser.Id == letter.SenderId);
                if (location != -1)
                {
                    string dateTime = Rabbit.Utils.DateTimeHelper.GetDateTimeFromString(letter.CreatedAt).ToLongTimeString();
                    ChatWindows[location].InsertNewMessage(letter.SenderScreenName, letter.Text, dateTime);

                    if (ChatWindows[location].IsVisible)
                    {
                        removedLetters.Add(letter);
                    }
                }
            }
        }

        bool SendLetter(long toUserID, string letter)
        {
            try
            {
                Letters.letterBL.SendLetter(toUserID, letter);
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);
                return false;
            }
            return true;
        }
    }
}
